home *** CD-ROM | disk | FTP | other *** search
/ Collection of Tools & Utilities / Collection of Tools and Utilities.iso / edit / pt20pc.zip / SEARCH.C < prev    next >
C/C++ Source or Header  |  1991-02-04  |  23KB  |  904 lines

  1. #include "pt.h"
  2. #include "string.h"
  3.  
  4. static unsigned char originalFromString[STRINGSIZE+1];
  5. static unsigned char fromString[STRINGSIZE+1];
  6. static unsigned char originalToString[STRINGSIZE+1];
  7. static unsigned char toString[STRINGSIZE+1];
  8.  
  9. void pascal
  10. /* XTAG:replaceText */
  11. replaceText(w)
  12.     struct window *w;
  13. {
  14.     extern struct window *selWindow;
  15.     extern long selBegin, selEnd;
  16.     extern int selMode;
  17.     extern unsigned char msgBuffer[];
  18.     extern unsigned char textBuffer[];
  19.     extern int ignoreCase;
  20.     extern int topOnFind;
  21.     extern long addPosition;
  22.     extern int nextChange;
  23.     extern struct changeItem *change;
  24.     extern unsigned int bytesLeft;
  25.     extern unsigned char *userMessages[];
  26.     extern unsigned int piecesLeft;
  27.     extern int debug;
  28.     extern struct openFile *files;
  29.  
  30.     struct window *saveSelWindow;
  31.     long saveSelBegin, saveSelEnd, repEnd;
  32.     int n, fileId, fromLength;
  33.     int nLines, verify, replace, nReplaces;
  34.     int inSelection, diffLengths;
  35.     int saveIgnoreCase;
  36.     long cp, toLength, fSize;
  37.     unsigned char ch, *s;
  38.     struct piece *tempPP, *newPP;
  39.     struct changeItem *thisChange;
  40.  
  41.     fileId = w->fileId;
  42.     fSize = fileSize(fileId);
  43.     nReplaces = 0;
  44.     
  45.     /* check if this is a readOnly file */
  46.     if( files[fileId].readOnly ) {
  47.         sprintf(msgBuffer, userMessages[READONLYFILE],
  48.             files[fileId].origName);
  49.         msg(msgBuffer, 1);
  50.         return;
  51.     }
  52.  
  53.     /* get the string to search for */
  54.     s = getInput("String to replace: ", originalFromString, 0);
  55.     /* ESCape or empty string cancels the replace */
  56.     if( s == NULL || s[0] == '\0' )
  57.         goto cancelReplace;
  58.     strncpy(originalFromString, s, STRINGSIZE+1);
  59.     s = originalFromString;
  60.  
  61.     /* process the string to handle the newline, CR, and LF escapes */
  62.     n = 0;
  63.     saveIgnoreCase = ignoreCase;
  64.     while( 1 ) {
  65.         ch = *s;
  66.         if( isupper(ch) && ignoreCase /* case insensitive */)
  67.             ch = tolower(ch);
  68.         switch( ch ) {
  69.         case '\\':
  70.             ch = *++s;
  71.             if( ch == 'r' )
  72.                 ch = '\r';
  73.             else if( ch == 'N' )
  74.                 ch = '\n';
  75.             else if( ch == 'n' ) {
  76.                 fromString[n++] = '\r';
  77.                 ch = '\n';
  78.             }
  79.             break;
  80.         default:
  81.             break;
  82.         }
  83.         fromString[n++] = ch;
  84.         if( ch == '\0' )
  85.             break;
  86.         ++s;
  87.         if( n >= STRINGSIZE )
  88.             --n;
  89.     }
  90.  
  91.     /* get the replacment string */
  92.     sprintf(msgBuffer, "Replace `%s' with: ", originalFromString);
  93.     s = getInput(msgBuffer, originalToString, 0);
  94.     if( s == NULL )
  95.         goto cancelReplace;
  96.     strncpy(originalToString, s, STRINGSIZE);
  97.     s = originalToString;
  98.     /* process the replacement string for escapes */
  99.     n = 0;
  100.     while( 1 ) {
  101.         ch = *s++;
  102.         switch( ch ) {
  103.         case '\\':
  104.             ch = *s++;
  105.             if( ch == 'r' )
  106.                 ch = '\r';
  107.             else if( ch == 'N' )
  108.                 ch = '\n';
  109.             else if( ch == 'n' ) {
  110.                 toString[n++] = '\r';
  111.                 ch = '\n';
  112.             }
  113.             break;
  114.         default:
  115.             break;
  116.         }
  117.         toString[n++] = ch;
  118.         if( ch == '\0' )
  119.             break;
  120.     }
  121.     
  122.     /* replace in the selection only? */
  123.     s = getInput("Globally (g) or Within Selection (s): ", "g", 1);
  124.     if( s == NULL )
  125.         goto cancelReplace;
  126.     else if( tolower(s[0]) == 'g' || s[0] == 'y' )
  127.         /* the getInput will return a 'y' of the left mouse button */
  128.         /* is clicked. Construe that as a 'g' and RMB ar an 's' */
  129.         inSelection = 0;
  130.     else
  131.         inSelection = 1;
  132.  
  133.     /* verify each replacement? */
  134.     s = getInput("Verify each change? (y or n): ", "y", 1);
  135.     if( s == NULL ) {
  136. cancelReplace:
  137.         msg("Replace cancelled", 1);
  138.         ignoreCase = saveIgnoreCase;
  139.         return;
  140.     }
  141.     /* save the verify boolean for later use */
  142.     verify = !(tolower(s[0]) == 'n');
  143.  
  144.     /* Create a piece for the replacement string and record it in */
  145.     /* the piece buffer.  This makes it easy to insert the replace */
  146.     /* string by copying this piece */
  147.     toLength = strlen(toString);
  148.     tempPP = getFreePiece();
  149.  
  150.     tempPP->file = ADDFILE;
  151.     tempPP->position = addPosition;
  152.     for(n = 0; n < (int)toLength; n++ )
  153.         writeChar(toString[n], addPosition++);
  154.     tempPP->length = toLength;
  155.  
  156.     /* start from the selection or the beginning */
  157.     if( inSelection ) {
  158.         cp = selBegin;
  159.         repEnd = selEnd;
  160.         w = selWindow;
  161.     } else {
  162.         if( w == selWindow )
  163.             cp = selBegin;
  164.         else
  165.             cp = 0;
  166.         repEnd = fSize;
  167.     }
  168.     
  169.     /* How will the replace change character counts? */
  170.     /* we need to adjust repEnd after each replace */
  171.     diffLengths = strlen(toString) - strlen(fromString);
  172.  
  173.     /* set things up so the line counts will be right */
  174.     if( readChar(fileId, cp) == '\n' )
  175.         nLines = 1;
  176.     else
  177.         nLines = 0;
  178.  
  179.     /* save the location of the current selection */
  180.     if( !verify ) {
  181.         saveSelWindow = selWindow;
  182.         saveSelBegin = selBegin;
  183.         saveSelEnd = selEnd;
  184.     }
  185.     
  186.     fromLength = strlen(fromString);
  187.  
  188. /* while loop to repeat the replace */
  189. while( 1 ) {
  190.  
  191.     if( !verify ) {
  192.         sprintf(msgBuffer, "Replace is %d%% completed",
  193.             (int)((100*cp)/fSize));
  194.         msg(msgBuffer, 1);
  195.     }
  196.  
  197.     /* find the string */
  198.     cp = searchSpans(fileId, cp, repEnd, fromString, fromLength, &n);
  199.     nLines += n;
  200.     if( cp == (long)(-1) )
  201.         break;
  202.     if( selWindow != w ) {
  203.         eraseSelection();
  204.         selWindow = w;
  205.     }
  206.     selBegin = cp;
  207.     selEnd = selBegin + fromLength - 1;
  208.     selMode = SELCHAR;
  209.  
  210.     /* remember where we came from */
  211.     selWindow->rowLastline = selWindow->numTopline;
  212.     
  213.     /* replace? */
  214.     if( verify ) {
  215.         /* put the selection on the third line */
  216.         if( selBegin >= selWindow->posBotline 
  217.          || selBegin < selWindow->posTopline ) {
  218.             n = 3;
  219.             selWindow->posTopline = prevLine(fileId, selBegin, &n);
  220.             selWindow->numTopline += nLines - n;
  221.         }
  222.         (void)indentToShowSelection(-1);
  223.         /* show the string we found */
  224.         if( topOnFind )
  225.             topWindow(selWindow);
  226.         redrawWindow(selWindow);
  227.         sprintf(msgBuffer,
  228. "[At %d%% of file] Replace this one? (y or n -- Esc to cancel) ",
  229.             (int)((100*cp)/fSize) );
  230.         s = getInput(msgBuffer, "y", 1);
  231.         if( s == NULL )
  232.             goto notFound;
  233.         replace = tolower(s[0])=='y';
  234.     } else
  235.         replace = 1;
  236.     
  237.     /* do the replace */
  238.     if( replace ) {
  239.         deleteChars(selWindow->fileId, NOUPDATE, 0);
  240.         
  241.         /* record in the change history */
  242.         IncrementNextChange();
  243.         thisChange = &change[nextChange];
  244.         thisChange->type = CINSERT;
  245.         thisChange->position = selBegin;
  246.         thisChange->length = toLength;
  247.         thisChange->fileId = selWindow->fileId;
  248.         newPP = getFreePiece();
  249.         newPP->file = ADDFILE;
  250.         newPP->position = tempPP->position;
  251.         newPP->length = toLength;
  252.         thisChange->firstPiece = newPP;
  253.         
  254.         copyPieces(tempPP, selWindow, selBegin, toLength, verify);
  255.         cp = selBegin;
  256.         /* as we change the length of the text in the file with */
  257.         /* a replacement, we have to adjust repEnd so that we  */
  258.         /* will not quit early */
  259.         repEnd += diffLengths;
  260.  
  261.         if( inSelection ) {
  262.             /* if we are not verifying, we want the final */
  263.             /* selection to be the same as the original */
  264.             /* selection even though we are replaceing */
  265.             /* inside it.  This makes the adjustment */
  266.             if( !verify )
  267.                 saveSelEnd += diffLengths;
  268.         }
  269.         ++nReplaces;
  270.         /* see if we are running out of space */
  271.         if( (bytesLeft < SPACELOW)  && (piecesLeft <= 10) ) {
  272.             msg(userMessages[LOWSPACEMSG], 3);
  273.             goto notFound;
  274.         }
  275.     } else
  276.         cp = selBegin + 1;
  277. }
  278.  
  279. notFound:
  280.     /* free the temp piece */
  281.     freePieces(tempPP);
  282.  
  283.     /* restore the previous selection */
  284.     if( !verify ) {
  285.         selWindow = saveSelWindow;
  286.         selBegin = saveSelBegin;
  287.         selEnd = saveSelEnd;
  288.         redrawWindow(selWindow);
  289.     }
  290.     sprintf(msgBuffer, "Made %d replacement%s", nReplaces,
  291.         nReplaces==1?"":"s");
  292.     msg(msgBuffer, 1);
  293.     ignoreCase = saveIgnoreCase;
  294. }
  295.  
  296. static unsigned char originalSearchString[STRINGSIZE+1];
  297. static unsigned char searchString[STRINGSIZE+1];
  298. static long foundCp;    /* used to return cp in on-interactive search */
  299.  
  300. long pascal
  301. /* XTAG:searchExternal */
  302. searchExternal(s, w, newSearchMode, newIgnoreCase)
  303.     unsigned char *s;
  304.     struct window *w;
  305.     int newSearchMode, newIgnoreCase;
  306. {
  307.     extern int ignoreCase;
  308.     extern int searchMode;
  309.  
  310.     int saveSearchMode, saveIgnoreCase;
  311.  
  312.     /* save and change the search mode state */
  313.     saveSearchMode = searchMode;
  314.     searchMode = newSearchMode;
  315.     saveIgnoreCase = ignoreCase;
  316.     ignoreCase = newIgnoreCase;
  317.  
  318.     strncpy(originalSearchString, s, STRINGSIZE+1);
  319.     searchFor(3, w);    /* 3 means non-int